var Snake = EventDispatcher.extend({
	head: null,
	tail: null,
	intervalDescriptor: null,
		
	constructor: function()
	{
		this.initialize();
	},
	
	destructor: function()
	{
		this.head.removeFromStage();
		this.head = null;
		this.intervalDescriptor = null;
		this.tail.destructor();
		this.tail = null;
	},
	
	restart: function()
	{
		this.destructor();
		this.initialize();
		this.startMoving();
	},
	
	initialize: function()
	{
		this.head = new SnakeHead(240, 240);
		this.tail = new SnakeTail(this.head.x, this.head.y + SnakeSegment.SIZE);
	},
	
	startMoving: function()
	{
		this.intervalDescriptor = setInterval(handler(this, 'move'), Snake.SPEED);
	},
	
	stopMoving: function()
	{
		clearInterval(this.intervalDescriptor);
	},
	
	setDirection: function(newDirection)
	{
		this.head.setDirection(newDirection);
	},
		
	move: function()
	{
		var newCoords = this.head.getNewCoords();
		if (!this.isCollided(newCoords))
		{
			var prevCoords = new Point(this.head.x, this.head.y);
			this.head.move(newCoords);
			this.tail.move(prevCoords);
			this.dispatchEvent('move');
		}
		else
		{
			this.dispatchEvent('collision');
		}
	},
	
	grow: function()
	{
		this.tail.grow(2);
	},
	
	containsCoords: function(x, y)
	{
		return this.head.hasCoords(x, y) || 
			this.tail.containsCoords(x, y);
	},
	
	isCollided: function(coords)
	{
		return this.didCollideWithBorders(coords) || this.didCollideWithSelf(coords);
	},

	didCollideWithSelf: function(coords)
	{
		return this.tail.containsCoords(coords.x, coords.y);
	},
	
	didCollideWithBorders: function(coords)
	{
		return ((coords.x < 0) || (coords.x + SnakeSegment.SIZE > stage.width) ||
				(coords.y < 0) || (coords.y + SnakeSegment.SIZE > stage.height));
	}
}, {
	SPEED: 100
});